#ifndef _HTTPCONFIG_H
#define _HTTPCONFIG_H

#include <vector>
#include <boost/asio.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/shared_ptr.hpp>
#include <hippolib/net/host.hpp>
#include "httpuserdb.h"

class RuleBase
{
public:
	RuleBase();
	RuleBase(const RuleBase & r);
	virtual ~RuleBase();

	RuleBase& operator=(const RuleBase & r);

	boost::shared_ptr<hippolib::host> getSource();
	bool setSource(const std::string & expr);
	boost::shared_ptr<hippolib::host> getDestination();
	bool setDestination(const std::string & expr);
private:
	hippolib::host* getHost(const std::string & expr);
	hippolib::host *m_src;
	hippolib::host *m_dst;
};

class AccessRule : public RuleBase
{
public:
	AccessRule();
	AccessRule(const AccessRule& r);
	virtual ~AccessRule();
	AccessRule & operator=(const AccessRule & r);

	int getAction();
	void setAction(int action);

	enum ACTIONS
	{
		ALLOW = 0,
		DENY,
		NOTFOUND
	};
private:
	int m_action;
};

class UpstreamProxy
{
public:
	UpstreamProxy();
	UpstreamProxy& operator=(const UpstreamProxy & p);
	std::string getName() const;
	void setName(const std::string & name);
	std::string getHost() const;
	void setHost(const std::string & host);
	unsigned short getPort() const;
	void setPort(unsigned short port);
	
private:
	std::string m_name;
	std::string m_host;
	unsigned short m_port;
};

class UpstreamRule : public RuleBase
{
public:
	UpstreamRule();
	UpstreamRule(const UpstreamRule & rule);
	virtual ~UpstreamRule();
	UpstreamRule& operator=(const UpstreamRule & rule);
	std::string getProxyName() const;
	void setProxyName(const std::string & name);
private:
	std::string m_proxyname;
};

class LogConfig
{
public:
	LogConfig();
	LogConfig(const LogConfig & config);
	LogConfig& operator=(const LogConfig & config);
	std::string m_name;
	std::string m_filename;
	std::string m_level;
	int m_backupindex;
};

class HTTPConfig
{
public:
	HTTPConfig();
	virtual ~HTTPConfig();
	HTTPConfig(const HTTPConfig & config);
	
	HTTPConfig & operator=(const HTTPConfig & config);
	boost::asio::ip::address getListeningAddress() const;
	unsigned short getListeningPort() const;
	void setHostname(const std::string & hostname);
	std::string getHostname() const;
	std::size_t getThreads() const;
	std::size_t getMaxHeaderBufferSize() const;
	std::vector<std::string> getUserDBFilename() const;
	std::vector<HTTPUser> getUsers() const;
	bool isAuthEnabled() const;
	std::vector<UpstreamProxy> getUpstreamProxies() const;
	bool isUpstreamEnabled() const;
	std::vector<UpstreamRule> getUpstreamRules() const;
	bool isAccessRuleEnabled() const;
	int getAccessRuleDefaultAction() const;
	std::vector<AccessRule> getAccessRules() const;
	std::string getProcUsername() const;
	std::string getProcGroupname() const;

	// log settings
	bool isLogEnabled() const;
	LogConfig getProxyLogConfig();
	LogConfig getAccessLogConfig();
	LogConfig getDebuggerConfig();

	// web-based gui settings
	bool isWebEnabled() const;
	boost::asio::ip::address getWebListeningAddress() const;
	unsigned short getWebListeningPort() const;
	std::string getWebDocRoot() const;
		
	enum
	{
		SUCCESS = 0,
		ERROR_FILE,
		ERROR_PARSE
	};
	
protected:
	boost::asio::ip::address m_listening_address;
	unsigned short m_listening_port;
	std::string m_hostname;
	std::size_t m_threads;

	// The user and group for this program to run, only available under linux
	std::string m_proc_username;
	std::string m_proc_groupname;
	
	std::size_t m_header_buffer_maxsz;
	bool m_isauthenabled;
	std::vector<std::string> m_userdbs;
	std::vector<HTTPUser> m_singleusers;
	std::vector<UpstreamProxy> m_upstream_proxies;
	bool m_isupstreamenabled;
	std::vector<UpstreamRule> m_upstream_rules;
	bool m_isaccess_rule_enabled;
	int m_access_default_action;
	std::vector<AccessRule> m_access_rules;

	// log settings
	bool m_log_enabled;
	LogConfig m_proxylog;
	LogConfig m_accesslog;
	LogConfig m_debugger;

	// web-based gui settings
	bool m_web_enabled;
	boost::asio::ip::address m_web_listenaddr;
	unsigned short m_web_listenport;
	std::string m_web_docroot;
};

#endif

